package org.yzbdl.lanius.orchestrate.system.controller;


import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.yzbdl.lanius.orchestrate.serv.dto.system.*;
import org.yzbdl.lanius.orchestrate.serv.service.system.OrgService;
import org.yzbdl.lanius.orchestrate.serv.service.system.UserAuthService;
import org.yzbdl.lanius.orchestrate.serv.service.system.UserService;
import org.yzbdl.lanius.orchestrate.serv.utils.CurrentUserUtil;
import org.yzbdl.lanius.orchestrate.serv.utils.VerifyCodeUtil;
import org.yzbdl.lanius.orchestrate.common.annotation.auth.CheckPermission;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprId;
import org.yzbdl.lanius.orchestrate.common.annotation.log.OprLog;
import org.yzbdl.lanius.orchestrate.common.chain.DeleteCheckChain;
import org.yzbdl.lanius.orchestrate.common.chain.DeleteExploreDto;
import org.yzbdl.lanius.orchestrate.common.exception.runtime.InvalidCodeException;
import org.yzbdl.lanius.orchestrate.common.result.ResultObj;
import org.yzbdl.lanius.orchestrate.common.constant.UserOprEventConstant;
import org.yzbdl.lanius.orchestrate.common.utils.MessageUtil;

import java.util.List;

/**
 *
 * @author chenjunhao@yzbdl.ac.cn
 * @date 2022/3/24
 */
@Api(tags = "用户相关接口")
@RestController
@RequestMapping("/user")
@Validated
public class UserController {

    @Autowired
    UserService userService;
    @Autowired
    UserAuthService userAuthService;
    @Autowired
    OrgService orgService;


    @OprLog(value = UserOprEventConstant.SYSTEM_USER_LOGIN,msg="用户<${userName}>执行登录操作")
    @ApiOperation(value="用户登录", notes="")
    @RequestMapping(value = "login", method = RequestMethod.POST)
    public ResultObj login(@RequestBody @Validated UserLoginParamDto userLoginParamDto,@RequestParam String key){
        if(VerifyCodeUtil.verify(key,userLoginParamDto.getCode())){
            return ResultObj.success(userAuthService.login(userLoginParamDto.getUserName(),userLoginParamDto.getPassword()));
        }
        throw new InvalidCodeException(MessageUtil.get("system.user.login.valid_code_fail"));
    }

    @ApiOperation(value="刷新token", notes="")
    @RequestMapping(value = "/refresh", method = RequestMethod.POST)
    public ResultObj refresh(@RequestBody @Validated TokenRefreshDto tokenRefreshDto){
        return ResultObj.success(userAuthService.refresh(tokenRefreshDto.getRefreshToken()));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_ADD,msg="新增用户<${userName}>")
    @CheckPermission("system::user::edit")
    @ApiOperation(value="新增用户", notes="")
    @RequestMapping(value = "", method = RequestMethod.POST)
    public ResultObj insertUser(@RequestBody @Validated UserInsertParamDto userInsertParamDto){
        return ResultObj.success(userService.insertUser(userInsertParamDto, CurrentUserUtil.getCurrentUserOrgId(),userInsertParamDto.isChief()));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_EDIT,msg="更改用户<${nickName}>")
    @CheckPermission("system::user::edit")
    @ApiOperation(value="更改用户", notes="")
    @RequestMapping(value = "", method = RequestMethod.PUT)
    public ResultObj updateUser(@RequestBody @Validated UserUpdateParamDto userUpdateParamDto){
        return ResultObj.success(userService.updateUser(userUpdateParamDto));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_EDIT,msg="更改了用户<${userName}>的所属角色")
    @CheckPermission("system::user::edit")
    @ApiOperation(value="保存用户角色", notes="")
    @RequestMapping(value = "/{userId}/roles", method = RequestMethod.POST)
    public ResultObj saveUserRole(@RequestBody List<Long> roleIds,@PathVariable(value = "userId") @OprId(server = UserService.class) Long userId){
        return ResultObj.success(userService.saveUserRoles(roleIds, userId));
    }

    @CheckPermission("system::user::query")
    @ApiOperation(value="根据id获取用户", notes="")
    @RequestMapping(value = "/{userId}", method = RequestMethod.GET)
    public ResultObj getById(@PathVariable(value = "userId") Long userId){
        return ResultObj.success(userService.getById(userId));
    }

    @CheckPermission("system::user::query")
    @ApiOperation(value="分页查询用户", notes="")
    @RequestMapping(value = "/query", method = RequestMethod.POST)
    public ResultObj queryByPage(@RequestParam(defaultValue = "20") int size, @RequestParam(defaultValue = "1") int page,@RequestBody @Validated UserListDto userListDto){
        return ResultObj.success(userService.listUserPage(userListDto,new Page<>(page,size)));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_PASSWORD_RESET,msg="重置用户<${userName}>的密码")
    @CheckPermission("system::user::edit")
    @ApiOperation(value="重置用户密码", notes="")
    @RequestMapping(value = "/{userId}/password", method = RequestMethod.POST)
    public ResultObj resetPassword(@PathVariable("userId") @OprId(server = UserService.class) Long userId){
        return ResultObj.success(userService.resetPassword(userId));
    }

    @CheckPermission("system::user::edit")
    @ApiOperation(value="设置用户状态", notes="")
    @OprLog(value = UserOprEventConstant.SYSTEM_USER_EDIT,msg="更改了用户<${userName}>的状态")
    @RequestMapping(value = "/{userId}/status", method = RequestMethod.POST)
    public ResultObj changeStatus(@PathVariable("userId") @OprId(server = UserService.class) Long userId, @RequestBody @Validated UserStatusDto userStatusDto){
        return ResultObj.success(userService.setUserState(userStatusDto.getStatus(),userId));
    }

    @OprLog(value = UserOprEventConstant.SYSTEM_USER_DELETE,msg="删除用户<${userName}>,id是<${id}>")
    @CheckPermission("system::user::delete")
	@ApiOperation(value="删除用户", notes="")
    @RequestMapping(value = "/{userId}", method = RequestMethod.DELETE)
	public ResultObj deleteById(@PathVariable("userId") @OprId(server = UserService.class) Long userId){
        DeleteExploreDto deleteExploreDto = new DeleteCheckChain()
				.addChain(() -> userService.deleteUserById(userId,CurrentUserUtil.getCurrentUserOrgId()))
                .process();
		return deleteExploreDto.isOk()?
				ResultObj.success(MessageUtil.get("notify.success")):ResultObj.error(deleteExploreDto.getReason());
	}


}
